/*
* Copyright (C) 2020 ~ 2024 chaigec All Rights Reserved.
*
* Author:     chaigec <chaigec@163.com>
* Maintainer: chaigec <chaigec@163.com>

 * Use of this source code is governed by MIT license that can be found in the
 * LICENSE file in the root of the source tree. All contributing project authors
 * may be found in the AUTHORS file in the root of the source tree.
*/

#include "MkRtmpUtil.h"
#include "MkUtil/MkLog.h"

CMkRtmpUtil CMkRtmpUtil::m_Instance;
CMkRtmpUtil::CMkRtmpUtil()
{
    m_MapRtmpProtocol["rtmp"] = ProtocolRtmp;
    m_MapRtmpProtocol["rtmpt"] = ProtocolRtmpt;
    m_MapRtmpProtocol["rtmps"] = ProtocolRtmps;
    m_MapRtmpProtocol["rtmpe"] = ProtocolRtmpe;
    m_MapRtmpProtocol["rtmfp"] = ProtocolRtmfp;
    m_MapRtmpProtocol["rtmpte"] = ProtocolRtmpte;
    m_MapRtmpProtocol["rtmpts"] = ProtocolRtmpts;
}

Uint32 CMkRtmpUtil::ParseRtmpUrl(const MkString& Url, MkRtmpProtocol& Protocol, MkString& Domain, Uint16& Port, MkString& AppName, MkString& Path)
{
    Uint32 ErrorCode = NoneError;
    size_t nPos = Url.find("://");
    if (MkString::npos == nPos) {
        return InvalidUrl;
    }

    MkString strProtocol = Url.substr(0, nPos);
    ErrorCode = m_Instance.GetProtocol(strProtocol, Protocol);
    MkCheckErrorLog(ErrorCode, "invalid protocol:%s\n", strProtocol.c_str());

    //set default port
    switch (Protocol) {
    case ProtocolRtmp:
        Port = 1935;
        break;
    default:
        break;
    }

    nPos += 3; //add "://"
    MkString UnParseStr = Url.substr(nPos);

    size_t nColPos = UnParseStr.find(":");
    size_t nSlashPos = UnParseStr.find("/");
    if (MkString::npos != nSlashPos) {
        Domain = UnParseStr.substr(0, nSlashPos);
        UnParseStr = UnParseStr.substr(nSlashPos + 1);
    } else {
        Domain = UnParseStr;
    }
    if (MkString::npos != nColPos && nColPos < Domain.size()) {
        Port = std::stoi(Domain.substr(nColPos + 1));
        Domain = Domain.substr(0, nColPos);
    }
    size_t nSlash2Pos = UnParseStr.find("/");
    if (MkString::npos != nSlash2Pos) {
        AppName = UnParseStr.substr(0, nSlash2Pos);
        Path = UnParseStr.substr(nSlash2Pos + 1);
    } else {
        return InvalidUrl;
    }
    size_t nLastShlashPost = UnParseStr.rfind("/");
    size_t nQuesPos = UnParseStr.find("?");
    if (MkString::npos != nQuesPos && MkString::npos != UnParseStr.find("slist=")) {
        Path = UnParseStr.substr(0, nQuesPos);
        UnParseStr = UnParseStr.substr(nQuesPos + 1);
    } else if (MkString::npos != UnParseStr.find("ondemand/")) {
        Path = "ondemand";
    }/* else {
        Path = UnParseStr.substr(0, nLastShlashPost);
    }*/
    return NoneError;
}

Uint32 CMkRtmpUtil::GetProtocol(const MkString& strProtocol, MkRtmpProtocol& Protocol)
{
    MkUnorderedMap<MkString, MkRtmpProtocol>::iterator it = m_MapRtmpProtocol.find(strProtocol);
    if (it != m_MapRtmpProtocol.end()) {
        Protocol = it->second;
        return NoneError;
    }
    MkErrorLog("invalid rtmp portocol:%s\n", strProtocol.c_str());
    Protocol = ProtocolRtmpUnDefined;
    return InvalidParams;
}

CMkRtmpUtil::~CMkRtmpUtil()
{

}
